﻿#pragma once
#include "AsContainerBasics.h"
#include "AsBinaryFile.h"
#include "AsCustomData.h"

__AS_JY(Update 2023.1.7)
namespace As {

	AS_MEMBER_CLASS_DECLARATION(Variant);
	class AS_BASIC_EXPORT Variant {
	public:
		Variant();
		Variant(Pointer value);
		Variant(Bool value);
		Variant(Int value);
		Variant(Int8 value);
		Variant(Int16 value);
		Variant(Int32 value);
		Variant(Int64 value);
		Variant(uInt value);
		Variant(uInt8 value);
		Variant(uInt16 value);
		Variant(uInt32 value);
		Variant(uInt64 value);
		Variant(Float value);
		Variant(Double value);
		Variant(const char* value);
		Variant(const Object& value);
		Variant(const String& value);
		Variant(const PointCloud& value);
		Variant(const cvPoint& value);
		Variant(const cvPoint2f& value);
		Variant(const cvPoint2d& value);
		Variant(const cvPoint3f& value);
		Variant(const cvRect& value);
		Variant(const cvMat& value);
		Variant(const IntArray& value);
		Variant(const Int64Array& value);
		Variant(const FloatArray& value);
		Variant(const DoubleArray& value);
		Variant(const StringArray& value);
		Variant(const cvPointArray& value);
		Variant(const cvPoint2fArray& value);
		Variant(const cvPoint2dArray& value);
		Variant(const cvPoint3fArray& value);
		Variant(const cvRectArray& value);
		Variant(const cvMatArray& value);
		Variant(const AsVariantPair& value);
		Variant(const AsVariantArray& value);
		Variant(const CustomData& value);
		static Variant fromVariant(const Variant& value);

	private:
		std::shared_ptr<AS_MEMBER_CLASS(Variant)> m;

	public:
		bool			isNull()						const;
		bool			isType(VariantType type)		const;
		std::string		strValue()						const;
		std::string		strType()						const;
		std::string		str(bool hasAddress = false)	const;
		int				type()							const;

	public:
		Object&				toObject()			;
		Pointer				toPointer()			;
		Bool&				toBool()			;
		Int8&				toInt8()			;
		Int16&				toInt16()			;
		Int&				toInt()				;
		Int32&				toInt32()			;
		Int64&				toInt64()			;
		uInt8&				toUInt8()			;
		uInt16&				toUInt16()			;
		uInt&				toUInt()			;
		uInt32&				toUInt32()			;
		uInt64&				toUInt64()			;
		Float&				toFloat()			;
		Double&				toDouble()			;
		String&				toString()			;
		PointCloud&			toPointCloud()		;
		cvPoint&			toCvPoint()			;
		cvPoint2f&			toCvPoint2f()		;
		cvPoint2d&			toCvPoint2d()		;
		cvPoint3f&			toCvPoint3f()		;
		cvRect&				toCvRect()			;
		cvMat&				toCvMat()			;
		IntArray&			toIntArray()		;
		Int64Array&			toInt64Array()		;
		FloatArray&			toFloatArray()		;
		DoubleArray&		toDoubleArray()		;
		StringArray&		toStringArray()		;
		cvPointArray&		toCvPointArray()	;
		cvPoint2fArray&		toCvPoint2fArray()	;
		cvPoint2dArray&		toCvPoint2dArray()	;
		cvPoint3fArray&		toCvPoint3fArray()	;
		cvRectArray&		toCvRectArray()		;
		cvMatArray&			toCvMatArray()		;
		Variant&			toVariant()			;
		AsVariantPair&		toVariantPair()		;
		AsVariantArray&		toVariantArray()	;
		CustomData&			toCustomData()		;
		const Object&			toObject()			const;
		const Pointer			toPointer()			const;
		const Bool&				toBool()			const;
		const Int8&				toInt8()			const;
		const Int16&			toInt16()			const;
		const Int&				toInt()				const;
		const Int32&			toInt32()			const;
		const Int64&			toInt64()			const;
		const uInt8&			toUInt8()			const;
		const uInt16&			toUInt16()			const;
		const uInt&				toUInt()			const;
		const uInt32&			toUInt32()			const;
		const uInt64&			toUInt64()			const;
		const Float&			toFloat()			const;
		const Double&			toDouble()			const;
		const String&			toString()			const;
		const PointCloud&		toPointCloud()		const;
		const cvPoint&			toCvPoint()			const;
		const cvPoint2f&		toCvPoint2f()		const;
		const cvPoint2d&		toCvPoint2d()		const;
		const cvPoint3f&		toCvPoint3f()		const;
		const cvRect&			toCvRect()			const;
		const cvMat&			toCvMat()			const;
		const IntArray&			toIntArray()		const;
		const Int64Array&		toInt64Array()		const;
		const FloatArray&		toFloatArray()		const;
		const DoubleArray&		toDoubleArray()		const;
		const StringArray&		toStringArray()		const;
		const cvPointArray&		toCvPointArray()	const;
		const cvPoint2fArray&	toCvPoint2fArray()	const;
		const cvPoint2dArray&	toCvPoint2dArray()	const;
		const cvPoint3fArray&	toCvPoint3fArray()	const;
		const cvRectArray&		toCvRectArray()		const;
		const cvMatArray&		toCvMatArray()		const;
		const Variant&			toVariant()			const;
		const AsVariantPair&	toVariantPair()		const;
		const AsVariantArray&	toVariantArray()	const;
		const CustomData&		toCustomData()		const;

	public:
		Variant clone() const;

	private:
		void read(AsBinaryFile& f);
		void write(AsBinaryFile& f) const;

	public:
		String toText();
		void fromText(const String& text);

	public:
		enum AccessOptions {
			NormalAccess	= 0x01,
			CompressAccess	= 0x02,
		};
		
		bool load(std::string filepath = "untitled.avar", int options = NormalAccess);
		bool save(std::string filepath = "untitled.avar", int options = NormalAccess);

	public:
		friend AsBinaryFile& operator<<(AsBinaryFile& f, const AsVariant& variant);
		friend AsBinaryFile& operator>>(AsBinaryFile& f, AsVariant& variant);

	};

	AsBinaryFile& operator<<(AsBinaryFile& f, const AsVariant& variant);
	AsBinaryFile& operator>>(AsBinaryFile& f, AsVariant& variant);

};


